package msa.ch03;

import java.io.IOException;
import java.io.InterruptedIOException;

import javax.microedition.io.Connector;
import javax.wireless.messaging.MessageConnection;
import javax.wireless.messaging.MessageListener;
import javax.wireless.messaging.MultipartMessage;

import msa.ch03.data.MessageDatabase;
import msa.ch03.data.StoredMessage;

public class MessageReceiver {

	private static final String MMS_URL = "mms://:1234";
	
	private final ReceiverRunnable runnable;
	
	private Thread thread = null;
	private MessageConnection connection = null;;
	
	private class ReceiverRunnable implements Runnable {

		protected boolean isAlive;
		
		public synchronized void run() {
			try {
				while (true) {
					wait();
					if (isAlive) {
						System.out.println("Receiving message...");
						MultipartMessage message = (MultipartMessage) connection.receive();
						StoredMessage storedMessage = new StoredMessage(message);
						MessageDatabase.getInstance().addMessage(storedMessage);
						System.out.println("Message received");
					} else {
						// Exit loop
						System.out.println("Exiting ReceiverRunnable thread");
						break;
					}
				}
			} catch (InterruptedException e) {
				throw new RuntimeException("ReceiverRunnable:" + e);
			} catch (InterruptedIOException e) {
				throw new RuntimeException("ReceiverRunnable:" + e);
			} catch (IOException e) {
				throw new RuntimeException("ReceiverRunnable:" + e);
			}
		}
		
	}
	
	public MessageReceiver() {
		runnable = new ReceiverRunnable();
	}
	
	public void start() {
		try {
			if (thread == null) {
				runnable.isAlive = true;
				thread = new Thread(runnable);
				thread.start();
				connection = (MessageConnection) Connector.open(MMS_URL);
				connection.setMessageListener(new MessageListener() {
					public void notifyIncomingMessage(MessageConnection conn) {
						synchronized (runnable) {
							runnable.notify();							
						}
					}
				});
			}
		} catch (IOException e) {
			stop();
			throw new RuntimeException("Error starting:" + e);
		}
	}
	
	public void stop() {
		synchronized(runnable) {
			try {
				if (thread != null) {
					runnable.isAlive = false;
					runnable.notify();
					connection.close();
				}
			} catch (IOException e) {
				throw new RuntimeException("IOException:" + e);
			} finally {
				thread = null;
				connection = null;
			}
		}
	}
	
}
